package com.yb.guigu.pick.activity.endpoint;

import com.yb.guigu.pick.activity.bean.WebsocketUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;

import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ma
 */
@Controller
@ServerEndpoint("/websocket/{userId}")
public class WebSocketEndpoint extends BaseWebSocketEndpoint{

    Logger logger = LoggerFactory.getLogger(this.getClass());

    // ConcurrentHashMap, 保证线程安全, static全局共享 session

    // 这里之所以static，是因为这个类不是单例的！！
    // 它虽然有@Controller注解，但是不适用Ioc容器中拿对象，每一次请求过来都是一个新的对象

    /**
     * 存放 session
     */

    private final static Map<String, WebsocketUser> USER_MAP=new ConcurrentHashMap<>(); //sessionId->User

    private final static Map<String, Session> SESSION_MAP=new ConcurrentHashMap<>(); //userId-->Session


    /**
     * OnOpen 在连接创建(用户进入聊天室)时触发
     *
     * @param session session
     * @param config  config
     */
    @OnOpen
    public void openSession(Session session, EndpointConfig config, @PathParam("userId") String userId) {
        // 将session存起来, 用于服务器向浏览器发送消息

        WebsocketUser websocketUser = new WebsocketUser();

        websocketUser.setUserId(userId);

        addUser(websocketUser,session);

        String res = "OnOpen [" + websocketUser.getUserId() + "] 进入房间";

        sendAll(res);

        logger.info(res);
    }


    /**
     * 响应字符串
     *
     * @param session session
     * @param message message
     */
    @OnMessage
    public void onMessage(Session session, String message,@PathParam("userId") String userId) {

        WebsocketUser user = getUser(session.getId());
        String res = "OnMessage [" + user.getUserId() + "] " + message;
        sendAll(res);
        logger.info(res);
    }

    /**
     * 响应字节流
     *
     * @param session session
     * @param message message
     */
    @OnMessage
    public void onMessage(Session session, byte[] message) {
        // 这个以后再说
    }

    /**
     * OnClose 在连接断开(用户离开聊天室)时触发
     *
     * @param session     session
     * @param closeReason closeReason
     */
    @OnClose
    public void closeSession(Session session, CloseReason closeReason,@PathParam("userId") String userId) {
        //记得移除相对应的session

        WebsocketUser user = removeUser(session.getId());

        String res = "OnClose [" + user.getUserId() + "] 离开了房间";
        sendAll(res);
        logger.info(res);
    }

    @OnError
    public void sessionError(Session session, Throwable throwable) {
        // 通常有异常会关闭 session
        try {
            session.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Map<String, WebsocketUser> getUserMap() {
        return USER_MAP;
    }

    @Override
    public Map<String, Session> getSessionMap() {
        return SESSION_MAP;
    }

}
